package com.xzy.java.bbb;

import lombok.extern.slf4j.Slf4j;

import java.io.Serializable;
import java.lang.reflect.*;
import java.util.Arrays;
import java.util.Map;

/**
 * 泛型类中的泛型变量
 *
 * @author xzy.xiao
 * @date 2023/3/8  15:13
 */
@Slf4j
public class BbbTest<K, V extends Number & Serializable> {
    private Map<K, V> map;

    public static void main(String[] args) throws NoSuchFieldException {
        Field field = BbbTest.class.getDeclaredField("map");
        Type genericType = field.getGenericType();

        /*
         * ParameterizedType：参数化类型，例如List<T>，Set<T>，Map<K,V>
         */
        if (genericType instanceof ParameterizedType) {
            ParameterizedType parameterizedType = (ParameterizedType) genericType;

            Type[] actualTypeArguments = parameterizedType.getActualTypeArguments();
            for (Type actualTypeArgument : actualTypeArguments) {

                /*
                 * TypeVariable：类型变量，指的是List<T>，Map<K,V>中的T，K，V
                 */
                if (actualTypeArgument instanceof TypeVariable) {
                    TypeVariable typeVariable = (TypeVariable) actualTypeArgument;

                    /*
                     * 获取类型变量的上届：也就是申明泛型的时候 extends 右边的东西，如果没有指定则是 Object
                     */
                    Type[] bounds = typeVariable.getBounds();
                    log.info(String.valueOf(Arrays.asList(bounds)));

                    /*
                     * 获取类型变量在源码中的名字：“T”，“K”，“V”
                     */
                    String name = typeVariable.getName();
                    log.info(name);

                    /*
                     * 获取类型变量的载体：
                     *     BbbTest<K, V extends Number & Serializable> => K,V 的载体就是 class com.xzy.java.bbb.BbbTest
                     */
                    GenericDeclaration genericDeclaration = typeVariable.getGenericDeclaration();
                    log.info(String.valueOf(genericDeclaration));
                }
            }
        }
    }
}
